﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TransformBLG
{
    public class ProcessFiles
    {
        /// <summary>
        /// Occurs when [on relog complete].
        /// </summary>
        public event EventHandler OnRelogComplete;
        /// <summary>
        /// Executes the relog.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <param name="fileLocation">The file location.</param>
        public void ExecuteRelog(string item, string fileLocation)
        {
            string arguments = string.Format(@"{0} -f CSV -o ""{1}""", item, fileLocation);

            System.Diagnostics.Process process = new System.Diagnostics.Process();

            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.UseShellExecute = true;
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal;
            startInfo.FileName = "relog";
            startInfo.Arguments = arguments;
            startInfo.Verb = "runas";
            process.StartInfo = startInfo;
            process.EnableRaisingEvents = true;
            process.Exited += process_Exited;

            process.Start();

        }

        /// <summary>
        /// Read and write CSV.
        /// </summary>
        /// <param name="oldFileLocation">The old file location.</param>
        /// <param name="newFileLocation">The new file location.</param>
        /// <returns></returns>
        public List<PerfItem> ReadWriteCSV(string oldFileLocation, string newFileLocation)
        {
            List<PerfItem> perfItems = new List<PerfItem>();
            bool isFirstRow = true;
            //the memory usage of the app can get very high depending on the size of the perlog. This was causing OOM ex.
            //to avoid this we will read from one file, one line, transform it, then right it to the new file to avoid
            //high memory usage. this will however tax the disk.

            using (CsvFileReader reader = new CsvFileReader(string.Format(@"{0}", oldFileLocation)))
            {
                using (CsvFileWriter writer = new CsvFileWriter(string.Format(@"{0}", newFileLocation)))
                {
                    List<string> row = new List<string>();
                    while (reader.ReadRow(row))
                    {
                        TransformCSV(ref perfItems, isFirstRow, row);

                        // I write the item to csv file now
                        isFirstRow = WriteToCSV(perfItems, isFirstRow, writer);
                    }
                }
            }

            return perfItems;
        }

        /// <summary>
        /// Transforms the CSV.
        /// </summary>
        /// <param name="perfItems">The perf items.</param>
        /// <param name="isFirstRow">if set to <c>true</c> [is first row].</param>
        /// <param name="row">The row.</param>
        private void TransformCSV(ref List<PerfItem> perfItems, bool isFirstRow, List<string> row)
        {
            bool isFirstItem = true;
            string firstItem = string.Empty;

            PerfItem item = default(PerfItem);
            int itemNum = 0;

            foreach (string s in row)
            {
                if (isFirstRow)
                {

                    item = new PerfItem(s);

                    if (item.IsValidItem)
                        perfItems.Add(item);
                }
                else if (isFirstItem)
                {
                    firstItem = s;
                    isFirstItem = false;
                }
                else
                {
                 
                    perfItems[itemNum].Date = firstItem;
                    perfItems[itemNum].Value = s;
                    itemNum++;

                }
            }
        }

        /// <summary>
        /// Writes to CSV.
        /// </summary>
        /// <param name="perfItems">The perf items.</param>
        /// <param name="isFirstRow">if set to <c>true</c> [is first row].</param>
        /// <param name="writer">The writer.</param>
        /// <returns></returns>
        private bool WriteToCSV(List<PerfItem> perfItems, bool isFirstRow, CsvFileWriter writer)
        {
            if (!isFirstRow)
            {
                foreach (PerfItem writeItem in perfItems)
                {

                    List<string> csvrow = new List<string>();
                    csvrow.Add(writeItem.Machine);
                    csvrow.Add(writeItem.Object);
                    csvrow.Add(writeItem.Instance);
                    csvrow.Add(writeItem.Counter);
                    csvrow.Add(writeItem.Value);
                    csvrow.Add(writeItem.Date);
                    writer.WriteRow(csvrow);

                }
            }
            else
            {
                List<string> header = new List<string>();
                header.Add("Machine");
                header.Add("Object");
                header.Add("Instance");
                header.Add("Counter");
                header.Add("Value");
                header.Add("DateTime");
                writer.WriteRow(header);
                isFirstRow = false;
            }
            return isFirstRow;
        }


        /// <summary>
        /// Handles the Exited event of the process control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void process_Exited(object sender, EventArgs e)
        {
            if(this.OnRelogComplete != null)
            {
                this.OnRelogComplete(this, new EventArgs());
            }
            

        }

    }
}
